package com.ruoyi.examination.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.examination.domain.*;
import com.ruoyi.examination.dto.PaperConfigDto;
import com.ruoyi.examination.mapper.*;
import com.ruoyi.examination.util.SnowflakeIdUtils;
import com.ruoyi.examination.vo.PaperConfigAddVo;
import com.ruoyi.examination.vo.PaperConfigSelectVo;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.examination.service.IPaperConfigService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 试卷信息设置Service业务层处理
 * 
 * @author hcc
 * @date 2025-10-21
 */
@Service
public class PaperConfigServiceImpl implements IPaperConfigService 
{
    @Autowired
    private PaperConfigMapper paperConfigMapper;

    @Autowired
    private QuestionGroupMapper questionGroupMapper;

    @Autowired
    private PaperConfigGroupMapper paperConfigGroupMapper;

    @Autowired
    private QuestionGroupRelationMapper questionGroupRelationMapper;

    @Autowired
    private PaperQuestionRelationMapper paperQuestionRelationMapper;

    @Autowired
    private ExamPaperMapper examPaperMapper;

    private SnowflakeIdUtils snowflakeIdUtils = new SnowflakeIdUtils(5,8);
    public static final String GROUP_TYPE_SINGLE_CHOICE = "1"; // 单选题组
    public static final String GROUP_TYPE_MULTIPLE_CHOICE = "2"; // 多选题组
    public static final String GROUP_TYPE_JUDGMENT = "3"; // 判断题组
    /**
     * 查询试卷信息设置
     * 
     * @param paperConfigId 试卷信息设置主键
     * @return 试卷信息设置
     */
    @Override
    public PaperConfig selectPaperConfigByPaperConfigId(String paperConfigId)
    {
        return paperConfigMapper.selectPaperConfigByPaperConfigId(paperConfigId);
    }

    /**
     * 查询试卷信息设置列表
     * 
     * @param paperConfig 试卷信息设置
     * @return 试卷信息设置
     */
    @Override
    public List<PaperConfig> selectPaperConfigList(PaperConfig paperConfig)
    {
        return paperConfigMapper.selectPaperConfigList(paperConfig);
    }

    /**
     * 新增试卷信息设置
     * 
     * @param paperConfig 试卷信息设置
     * @return 结果
     */
    @Override
    public int insertPaperConfig(PaperConfig paperConfig)
    {
        paperConfig.setCreateBy(SecurityUtils.getUsername());
        paperConfig.setPaperConfigId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
        paperConfig.setCreateTime(DateUtils.getNowDate());
        return paperConfigMapper.insertPaperConfig(paperConfig);
    }

    /**
     * 修改试卷信息设置
     * 
     * @param paperConfig 试卷信息设置
     * @return 结果
     */
    @Override
    public int updatePaperConfig(PaperConfig paperConfig)
    {
        paperConfig.setUpdateTime(DateUtils.getNowDate());
        return paperConfigMapper.updatePaperConfig(paperConfig);
    }

    /**
     * 批量删除试卷信息设置
     * 
     * @param paperConfigIds 需要删除的试卷信息设置主键
     * @return 结果
     */
    @Override
    public int deletePaperConfigByPaperConfigIds(String[] paperConfigIds)
    {
        return paperConfigMapper.deletePaperConfigByPaperConfigIds(paperConfigIds);
    }

    /**
     * 删除试卷信息设置信息
     * 
     * @param paperConfigId 试卷信息设置主键
     * @return 结果
     */
    @Override
    public int deletePaperConfigByPaperConfigId(String paperConfigId)
    {
        return paperConfigMapper.deletePaperConfigByPaperConfigId(paperConfigId);
    }

    /**
     * 添加试卷信息设置
     * @param paperConfigAddVo
     * @return
     */
    @Override
    public int addPaperConfig(PaperConfigAddVo paperConfigAddVo) {
        PaperConfig paperConfig = new PaperConfig();
        BeanUtils.copyProperties(paperConfigAddVo,paperConfig);
        if (StringUtils.isNotEmpty(paperConfigAddVo.getTrainingProjectId())){
            Projects projects = questionGroupMapper.selectProjectName(paperConfigAddVo.getTrainingProjectId());
            if (StringUtils.isNotNull(projects)){
                paperConfig.setProjectMap(projects.getExampleOne());
            }
        }
        paperConfig.setPaperConfigId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
        Long singleChoiceCount = 0l;
        Long multipleChoiceCount = 0l;
        Long judgmentCount = 0l;
        List<PaperConfigGroup> paperConfigGroupList = paperConfigAddVo.getPaperConfigGroupList();
        if (CollectionUtils.isNotEmpty(paperConfigGroupList)){
            List<String> groupIds = paperConfigGroupList.stream().map(PaperConfigGroup::getGroupId).collect(Collectors.toList());
            // 查询题组信息通过groupIds
            List<QuestionGroup> questionGroups = questionGroupMapper.selectQuestionGroupByGroupIds(groupIds);
            // 转换为Map，便于快速通过groupId获取题组信息
            Map<String, QuestionGroup> groupMap = questionGroups.stream()
                    .collect(Collectors.toMap(QuestionGroup::getGroupId, group -> group, (existing, replacement) -> existing)); // 处理重复ID
            for (PaperConfigGroup paperConfigGroup : paperConfigGroupList) {
                paperConfigGroup.setScoreTotals(paperConfigGroup.getScoreQuestion() * paperConfigGroup.getPropositionCount());
                paperConfigGroup.setPaperConfigGroupId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
                paperConfigGroup.setCreateTime(DateUtils.getNowDate());
                paperConfigGroup.setCreateBy(SecurityUtils.getUsername());
                paperConfigGroup.setPaperConfigId(paperConfig.getPaperConfigId());
                paperConfigGroupMapper.insertPaperConfigGroup(paperConfigGroup);
                QuestionGroup questionGroup = groupMap.get(paperConfigGroup.getGroupId());
                if (questionGroup != null) {
                    // 用switch-case替代多if，逻辑更清晰
                    switch (questionGroup.getGroupType()) {
                        case GROUP_TYPE_SINGLE_CHOICE:
                            singleChoiceCount += questionGroup.getQuestionCount();
                            break;
                        case GROUP_TYPE_MULTIPLE_CHOICE:
                            multipleChoiceCount += questionGroup.getQuestionCount();
                            break;
                        case GROUP_TYPE_JUDGMENT:
                            judgmentCount += questionGroup.getQuestionCount();
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        paperConfig.setHasExamined("2");
        paperConfig.setDelFlag("0");
        paperConfig.setSingleChoiceCount(singleChoiceCount);
        paperConfig.setMultipleChoiceCount(multipleChoiceCount);
        paperConfig.setJudgmentCount(judgmentCount);
        paperConfig.setCreateBy(SecurityUtils.getUsername());
        paperConfig.setCreateTime(DateUtils.getNowDate());
        return paperConfigMapper.insertPaperConfig(paperConfig);
    }

    /**
     * 修改试卷信息设置
     * @param paperConfigAddVo
     * @return
     */
    @Override
    public int editPaperConfig(PaperConfigAddVo paperConfigAddVo) {
        PaperConfig paperConfig = new PaperConfig();
        BeanUtils.copyProperties(paperConfigAddVo,paperConfig);
        if (StringUtils.isNotEmpty(paperConfigAddVo.getPaperConfigGroupList())){
            paperConfigGroupMapper.deletePaperConfigGroupByPaperConfigId(paperConfigAddVo.getPaperConfigId());
            for (PaperConfigGroup paperConfigGroup : paperConfigAddVo.getPaperConfigGroupList()) {
                paperConfigGroup.setScoreTotals(paperConfigGroup.getScoreQuestion() * paperConfigGroup.getPropositionCount());
                paperConfigGroup.setPaperConfigGroupId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
                paperConfigGroup.setCreateTime(DateUtils.getNowDate());
                paperConfigGroup.setCreateBy(SecurityUtils.getUsername());
                paperConfigGroupMapper.insertPaperConfigGroup(paperConfigGroup);
            }
        }
        paperConfig.setUpdateBy(SecurityUtils.getUsername());
        paperConfig.setUpdateTime(DateUtils.getNowDate());
        return paperConfigMapper.updatePaperConfig(paperConfig);
    }

    /**
     * 获取列表
     * @param paperConfigSelectVo
     * @return
     */
    @Override
    public List<PaperConfigDto> getList(PaperConfigSelectVo paperConfigSelectVo) {
        List<PaperConfig> list = paperConfigMapper.getList(paperConfigSelectVo);
        List<PaperConfigDto> collect = list.stream().map(paperConfig -> {
            PaperConfigDto paperConfigDto = new PaperConfigDto();
            BeanUtils.copyProperties(paperConfig, paperConfigDto);
            // 获取试卷题组关联信息
            List<PaperConfigGroup> paperConfigGroupList = paperConfigGroupMapper.selectPaperConfigGroupByPaperConfigId(paperConfig.getPaperConfigId());
            if (CollectionUtils.isNotEmpty(paperConfigGroupList)) {
                StringJoiner names = new StringJoiner(";");
                StringJoiner counts = new StringJoiner(";");
                for (PaperConfigGroup paperConfigGroup : paperConfigGroupList) {
                    // 获取题组信息
                    QuestionGroup questionGroup = questionGroupMapper.selectQuestionGroupByGroupId(paperConfigGroup.getGroupId());
                    if (questionGroup != null){
                        names.add(questionGroup.getGroupName());
                        counts.add(paperConfigGroup.getPropositionCount().toString());
                    }
                }
                paperConfigDto.setQuestionGroupCounts(counts.toString());
                paperConfigDto.setQuestionGroupMap(names.toString());
            }
            return paperConfigDto;
        }).collect(Collectors.toList());
        return collect;
    }

    /**
     * 获取试卷信息
     * @param paperConfigId
     * @return
     */
    @Override
    public PaperConfigDto getPaperConfigInfo(String paperConfigId) {
        PaperConfigDto paperConfigDto = new PaperConfigDto();
        PaperConfig paperConfig = paperConfigMapper.selectPaperConfigByPaperConfigId(paperConfigId);
        if (paperConfig != null) {
            BeanUtils.copyProperties(paperConfig, paperConfigDto);
            List<PaperConfigGroup> paperConfigGroupList = paperConfigGroupMapper.selectPaperConfigGroupByPaperConfigId(paperConfig.getPaperConfigId());
            if (CollectionUtils.isNotEmpty(paperConfigGroupList)) {
                List<PaperConfigGroup> configGroupList = paperConfigGroupList.stream().map(paperConfigGroup -> {
                    QuestionGroup questionGroup = questionGroupMapper.selectQuestionGroupByGroupId(paperConfigGroup.getGroupId());
                    paperConfigGroup.setGroupName(questionGroup.getGroupName());
                    paperConfigGroup.setQuestionCount(questionGroup.getQuestionCount());
                    paperConfigGroup.setGroupType(questionGroup.getGroupType());
                    return paperConfigGroup;
                }).collect(Collectors.toList());
                paperConfigDto.setPaperConfigGroupList(configGroupList);
            }
        }
        return paperConfigDto;
    }

    /**
     * 生成试卷
     * @param examSchedule
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int generatedPaper(ExamSchedule examSchedule) {
        int result = 0;
        PaperConfig paperConfig = paperConfigMapper.selectPaperConfigByPaperConfigId(examSchedule.getPaperConfigId());
        if (examSchedule.getCounts() > 0){
            for (int i = 0; i < examSchedule.getCounts(); i++) {
                // 试卷信息
                ExamPaper examPaper = new ExamPaper();
                examPaper.setExamPaperId(String.valueOf(snowflakeIdUtils.nextId()));
                examPaper.setCreateBy(SecurityUtils.getUsername());
                examPaper.setCreateTime(DateUtils.getNowDate());
                examPaper.setDelFlag("0");
                examPaper.setExamStartTime(examSchedule.getExamStartTime());
                examPaper.setExamEndTime(examSchedule.getExamEndTime());
                examPaper.setExamDuration(String.valueOf(examSchedule.getExamDuration()));
                examPaper.setPaperConfigId(paperConfig.getPaperConfigId());
                examPaper.setExamPaperName(paperConfig.getPaperConfigName());
                examPaper.setExamNotes(examSchedule.getRemark());
                examPaper.setTrainingClassId(examSchedule.getTrainingClassId());
                boolean hasQuestions = false;
                if (paperConfig != null) {
                    List<PaperConfigGroup> paperConfigGroupList = paperConfigGroupMapper.selectPaperConfigGroupByPaperConfigId(paperConfig.getPaperConfigId());
                    if (CollectionUtils.isNotEmpty(paperConfigGroupList)) {
                        for (PaperConfigGroup paperConfigGroup : paperConfigGroupList) {
                            // 获取题组信息
                            List<QuestionGroupRelation> questionGroupRelationList = questionGroupRelationMapper.selectQuestionGroupRelationByGroupId(paperConfigGroup.getGroupId());
                            // 获取题组关联的题目
                            List<String> allQuestionIds = questionGroupRelationList.stream().map(QuestionGroupRelation::getQuestionId).collect(Collectors.toList());
                            // 根据题量随机抽取题目
                            List<String> questionIds = randomSelect(allQuestionIds, paperConfigGroup.getPropositionCount());
                            if (StringUtils.isNotEmpty(questionIds)){
                                hasQuestions = true;
                                String questionType = paperConfigGroup.getGroupType();
                                // 批量插入关联
                                List<PaperQuestionRelation> relations = buildPaperQuestionRelations(examPaper.getExamPaperId(), questionIds, questionType);
                                paperQuestionRelationMapper.batchInsertRelation(relations);
                            }
                        }
                    }
                }
                if (!hasQuestions){
                    continue;
                }
                examPaperMapper.insertExamPaper(examPaper);
            }
            ExamPaper examPaperVo = new ExamPaper();
            examPaperVo.setTrainingClassId(examSchedule.getTrainingClassId());
            examPaperVo.setPaperConfigId(examSchedule.getPaperConfigId());
            List<ExamPaper> examPapers = examPaperMapper.selectExamPaperList(examPaperVo);
            result = examPapers.size();
        }
        return result;
    }

    /**
     * 逻辑删除
     * @param paperConfigIds
     * @return
     */
    @Override
    public int logicalRemove(String[] paperConfigIds) {
        return paperConfigMapper.logicalRemove(paperConfigIds);
    }

    private List<PaperQuestionRelation> buildPaperQuestionRelations(String examPaperId, List<String> questionIds, String questionType) {
        // 按题目抽取顺序，分配 groupSort（1,2,3...）
        List<PaperQuestionRelation> relations = new ArrayList<>();
        for (int i = 0; i < questionIds.size(); i++) {
            String questionId = questionIds.get(i);
            PaperQuestionRelation relation = new PaperQuestionRelation();
            relation.setPaperQuestionId(String.valueOf(snowflakeIdUtils.nextId()));
            relation.setExamPaperId(examPaperId);
            relation.setQuestionId(questionId);
            relation.setQuestionType(questionType);
            // 核心：同一题型内，按抽取顺序从1开始编号
            relation.setQuestionSort(Long.valueOf(i + 1));

            relations.add(relation);
        }
        return relations;
    }

    private List<String> randomSelect(List<String> allQuestionIds, Long propositionCount) {
        if (CollectionUtils.isEmpty(allQuestionIds)) {
            return Collections.emptyList();
        }
        // 若需要的数量大于总数量，返回全部
        if (propositionCount >= allQuestionIds.size()) {
            return new ArrayList<>(allQuestionIds);
        }
        // 随机打乱并截取前propositionCount个
        List<String> shuffled = new ArrayList<>(allQuestionIds);
        Collections.shuffle(shuffled);
        return shuffled.subList(0, propositionCount.intValue());
    }
}
